package com.XSQS.storage.index;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import com.XSQS.storage.StorageManager;
import com.XSQS.storage.helper.FileName;
import com.XSQS.storage.manager.QueryInterface;
import com.XSQS.storage.util.XMLSubTree;
import com.XSQS.util.Utility;

public class IndexManager {

	private static IndexManager instance;

	private Logger logger = Utility.getLogger(IndexManager.class);

	private InvertedCreater creater;

	private InvertedMerger merger;

	private InvertedSearcher searcher;

	private StorageManager storageManager = null;

	private IndexManager() {
		creater = InvertedCreater.getInstance();
		merger = InvertedMerger.getInstance();
		searcher = InvertedSearcher.getInstance();
	}

	public synchronized static IndexManager getInstance() {
		if (instance == null) {
			instance = new IndexManager();
		}
		return instance;
	}

	public void createIndex(XMLSubTree xmlSubTree) {
		if (existsIndex()) {
			merger.merge2Index(xmlSubTree);
		} else {
			creater.createIndex(xmlSubTree);
		}
	}

	public IndexEntry[] search(String key) {
		return searcher.search(key);
	}

	public IndexEntry[] searchForMultiKeys(String keys) {
		return searcher.searchForMultiKeys(keys);
	}

	/**
	 * Search the IndexEntry[] of which exactly match the sentence. The
	 * StorageManager needs to be set before invoking this method.
	 * 
	 * @param sentence
	 * @return
	 * @throws Exception
	 */
	public IndexEntry[] searchForExactMatch(String sentence) throws Exception {
		if (storageManager == null) {
			Exception e = new Exception(
					"The StorageManager needs to be set before invoking this method.");
			logger.error(e.getMessage());
			throw e;
		}
		QueryInterface queryInterface = storageManager.getQueryInterface();
		IndexEntry[] entries = searchForMultiKeys(sentence);
		List<IndexEntry> list = new LinkedList<IndexEntry>();
		int num = entries == null ? 0 : entries.length;
		for (int i = 0; i < num; ++i) {
			String value = queryInterface.getValue(entries[i].getOffset(),
					entries[i].getLen(), entries[i].getDocID());
			if (value.equals(sentence))
				list.add(entries[i]);
		}
		entries = new IndexEntry[list.size()];
		return list.toArray(entries);
	}

	private boolean existsIndex() {
		String fileName = FileName.getIndexEntriesFile();
		File file = new File(fileName);
		return file.exists();
	}

	public void setStorageManager(StorageManager storageManager) {
		this.storageManager = storageManager;
	}

	public StorageManager getStorageManager() {
		return storageManager;
	}
}
